/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import sqlcommand.MyError;


/**
 *
 * @author GREENWIND
 */
public class Table implements Serializable {

    private String tableName;
    private int nCols;
    private ArrayList<Column> listCol;
    private List<Row> listRows;
    private int posPrimary; // vi tri cot la primaryKey

    public Table(ArrayList<Column> cols, String name) {
        listCol = cols;
        nCols = cols.size();
        tableName = name;
    }
    public Table(){
        listCol = new ArrayList<>();
        listRows = new ArrayList<>();
    }

    public Table(String name) {
        nCols = 0;
        this.tableName = name;      
        listRows = new ArrayList<>();
        listCol = new ArrayList<>();
    }

    /**
     * them 1 dong vao trong bang
     *
     * @param row: dong can chen them vao
     * @return True: chen thanh cong false: that bai
     */
    public Boolean insertRowHasCheckPrimary(Row row) {
        // kiem tra khoa chinh
        for (int i = 0; i < this.getListRows().size(); i++) {
            Row r = getListRows().get(i);
            if (r.getListCell().get(this.getPosPrimary()).getData().equals(row.getListCell().get(this.getPosPrimary()).getData())) {
                return false;
            }
        }

        // set kieu du lieu cho tung cell
       return insertRow(row);
    }
    
    public Boolean insertRow(Row row) {
        

        // set kieu du lieu cho tung cell
        for (int i = 0; i < getnCols(); i++) {
            row.getListCell().get(i).setDataType(getListCol().get(i).getType());
        }
        return getListRows().add(row);
    }

    /**
     * chen them mot cot vao ben trai 
     * @param col
     * @return 
     */
    public Boolean insertColumn(Column col){
        // kiem tra xem cot da ton tai chua
        for(int i=0; i<nCols; i++){
            if(listCol.get(i).getName().equals(col.getName()))
                return false;
        }
        
        return listCol.add(col);
    }
    /**
     * delete cot
     *
     * @param columnId
     * @return
     */
    public Boolean deleteColumn(int posColumn) {
        try {
            for (int i = 0; i < getListRows().size(); i++) { // xoa trong tung dong
                getListRows().get(i).deleteCell(posColumn);
            }
            getListCol().remove(posColumn);

            return true;
        } catch (Exception e) {
            System.out.println(e.toString());
            return false;
        }
    }

    /**
     * them mot cot vao bang
     * @param name
     * @param type: kieu du lieu  0. so, 1. Chuoi
     * @return 
     */
   
    public Boolean deleteRow(int rowId) {
        if (rowId < 0 || rowId >= getListRows().size()) {
            return false;
        }
        getListRows().remove(rowId);
        return true;
    }
    public Boolean deleteRow(Row row){
        return getListRows().remove(row);
    }

    public Boolean update(int rowId, Row newRow) {
        if (rowId < 0 || rowId >= getListRows().size()) {
            return false;
        }
        getListRows().add(rowId, newRow);
        return true;
    }

    /**
     * lay cac dong thoa dieu kien
     *
     * @param colums: cot xet dieu kien
     * @param coditions: dieu kien tuong ung
     * @param operator: toan tu <, <=, >, =>, !=, =
     * @return cac dong thoa dieu kien
     */
    public List<Row> selectRow(String colums, String conditions, String operator) {
        List<Row> rows = new ArrayList<Row>();
        int nRows = getListRows().size();

        // duyet danh sach cac dong
        for (int i = 0; i < nRows; i++) {
            List<Cell> cells = getListRows().get(i).getListCell();
            // duyet danh sach cac cell
            for (int j = 0; j < cells.size(); j++) {
                Cell cell = cells.get(j);
                MyError err = new MyError();
                if (cell.getName().equals(colums)
                        && compare(cell.getData(), conditions, operator, err)
                        && err.getError() == null) {
                    rows.add(getListRows().get(i));
                }
            }
        }
        return rows;
    }

    public List<Row> selectRow(String[] colums, ArrayList<Condition> cons, String connective) {
        List<Row> rows = new ArrayList<Row>();
        int nRows = getListRows().size();

        // duyet danh sach cac dong
        for (int i = 0; i < nRows; i++) {
            List<Cell> cells = getListRows().get(i).getListCell();
            // duyet danh sach cac cell
            for (int j = 0; j < cells.size(); j++) {
                Cell cell = cells.get(j);
                MyError err = new MyError();


            }
        }
        return rows;
    }

    /**
     * So sanh 2 chuoi hoac so nhap vao
     *
     * @param part1
     * @param part2
     * @param operator
     * @return
     */
    public Boolean compare(String part1, String part2, String operator, MyError err) {
        // neu ca 2 la so

        int index = -1;
        if ("<".equals(operator)) {
            index = 0;
        }
        if ("<=".equals(operator)) {
            index = 1;
        }
        if (">".equals(operator)) {
            index = 2;
        }
        if (">=".equals(operator)) {
            index = 3;
        }
        if ("!=".equals(operator)) {
            index = 4;
        }
        if ("=".equals(operator)) {
            index = 5;
        }

        if (isNumber(part1) && isNumber(part2)) {
            int op1 = Integer.parseInt(part1);
            int op2 = Integer.parseInt(part2);

            switch (index) {
                case 0:
                    return op1 < op2;
                case 1:
                    return op1 <= op2;
                case 2:
                    return op1 > op2;
                case 3:
                    return op1 >= op2;
                case 4:
                    return op1 != op2;
                case 5:
                    return op1 == op2;
                case 7:
                    return op1 < op2;
                default: {
                    err.setError("Cannot excute this operator in number!!!");
                    return false;
                }
            }

        } else {
            switch (index) {
                case 4:
                    return !part1.equals(part2);
                case 5:
                    return part1.equals(part2);
                default: {
                    err.setError("Cannot excute this operator in text!!!");
                    return false;
                }
            }
        }

    }

    public Boolean isNumber(String s) {
        try {
            Integer.parseInt(s);
            return true;
        } catch (NumberFormatException ex) {
            return false;
        }
    }

    /**
     * thuc hien phep tich descartes 2 bang lai
     * @param other
     * @return bang co chua tat ca cac cot khong trung nhau cua 2 bang thua so
     */
    public Table Descartes(Table other){
        Table t = new Table();
        ArrayList<Column> cols = this.getListCol();
        boolean addAll = cols.addAll(other.getListCol());
        if(!addAll)
            return null;
       
        t.setListCol(listCol);
        // ghep noi cac dong lai voi nhau
        for(int i=0; i<this.getnRows(); i++){
            
            for(int j=0; j<other.getnRows(); j++){
                Row ri = new Row(this.getListRows().get(i));
                Row rj = other.getListRows().get(j);
                if(!ri.appendCell((ArrayList)rj.getListCell()))
                    return null;
                
                t.insertRow(ri);                
            }
        }
        
        
        
        // xoa cac cot trung nhau
//        int nCol = t.getnCols();
//        for(int i=0; i<nCol-1; i++){
//            for(int j=i+1; j<nCol; j++){
//                if(t.getListCol().get(i).getName().equals(t.getListCol().get(j).getName())){
//                    t.deleteColumn(j);
//                }
//            }
//        }
        return t;
    }

    /**
     * @return the tableName
     */
    public String getTableName() {
        return tableName;
    }

    /**
     * @param tableName the tableName to set
     */
    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    /**
     * @return the nCols
     */
    public int getnCols() {
        return listCol.size();
    }

    /**
     * @param nCols the nCols to set
     */
    public void setnCols(int nCols) {
        this.nCols = nCols;
    }

    /**
     * @return the listCol
     */
    public ArrayList<Column> getListCol() {
        return listCol;
    }

    /**
     * @param listCol the listCol to set
     */
    public void setListCol(ArrayList<Column> listCol) {
        this.listCol = listCol;
    }

    /**
     * @return the listRows
     */
    public List<Row> getListRows() {
        return listRows;
    }

    /**
     * @param listRows the listRows to set
     */
    public void setListRows(List<Row> listRows) {
        
        for(int i=0; i<listRows.size(); i++){
            for(int j=0; j<listRows.get(i).getListCell().size(); j++){
                listRows.get(i).getListCell().get(j).setTableName(tableName);
            }
        }
        this.listRows = listRows;
    }

    /**
     * @return the posPrimary
     */
    public int getPosPrimary() {
        return posPrimary;
    }

    /**
     * @param posPrimary the posPrimary to set
     */
    public void setPosPrimary(int posPrimary) {
        this.posPrimary = posPrimary;
    }

    private int getnRows() {
        return getListRows().size();
    }

    

  
   
}